#include "EPSG/Transform.h"

/* System Includes */
#ifdef WIN32
	#include <Windows.h>
#endif

/* OpenGL Includes */
#include <GL/GL.h>
#include <GL/GLU.h>

#include "EPSG/Vec3.h"

EPSG::Transform::Transform()
{
	_tMatrix.setIdentity();
}

void EPSG::Transform::setupCamera()
{
	glMultMatrixf( _tMatrix.invert().getAsArray() );
	_parent->setupCamera();
}

void EPSG::Transform::setupLights()
{
	_parent->setupLights();
	glMultMatrixf( _tMatrix.getAsArray() );
}

void EPSG::Transform::render()
{
	glPushMatrix();
	glMultMatrixf( _tMatrix.getAsArray() );
	Group::render();
	glPopMatrix();
}

void EPSG::Transform::translate( float x, float y, float z )
{
	glPushAttrib( GL_TRANSFORM_BIT );
	glMatrixMode( GL_MODELVIEW );
	glPushMatrix();
	glLoadMatrixf( _tMatrix.getAsArray() );
	glTranslatef( x, y, z );
	glGetFloatv( GL_MODELVIEW_MATRIX, _tMatrix.getAsArray() );
	glPopMatrix();
	glPopAttrib();
}

void EPSG::Transform::rotate( float angle, float x, float y, float z )
{
	glPushAttrib( GL_TRANSFORM_BIT );
	glMatrixMode( GL_MODELVIEW );
	glPushMatrix();
	glLoadMatrixf( _tMatrix.getAsArray() );
	glRotatef( angle, x, y, z );
	glGetFloatv( GL_MODELVIEW_MATRIX, _tMatrix.getAsArray() );
	glPopMatrix();
	glPopAttrib();
}

void EPSG::Transform::rotate( float x, float y, float z )
{
	EPSG::Vec3<float> v = EPSG::Vec3<float>( x, y, z );
	if( x < 0 )
		x = -1;
	else if( x > 0 )
		x = 1;
	if( y < 0 )
		y = -1;
	else if( y > 0 )
		y = 1;
	if( z < 0 )
		z = -1;
	else if( z > 0 )
		z = 1;

	rotate( v.normalize(), x, y, z );
}

void EPSG::Transform::scale( float x, float y, float z )
{
	glPushAttrib( GL_TRANSFORM_BIT );
	glMatrixMode( GL_MODELVIEW );
	glPushMatrix();
	glLoadMatrixf( _tMatrix.getAsArray() );
	glScalef( x, y, z );
	glGetFloatv( GL_MODELVIEW_MATRIX, _tMatrix.getAsArray() );
	glPopMatrix();
	glPopAttrib();
}

std::string EPSG::Transform::getType()
{
	return "TRANSFORM";
}